package com.easypan.util;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.math.BigDecimal;

public class ScaleFilter {
    private static final Logger logger = LoggerFactory.getLogger(ScaleFilter.class);




    /**
     * 生成视频的缩略图
     * 这就是调用ffmpeg的方法，通过视频生成缩略图即封面
     * @param sourceFile 需要进行缩略的视频路径
     * @param width 形成封面的宽度
     * @param targetFile 生成的封面路径
     */
    public static void createCover4Video(File sourceFile, Integer width, File targetFile) {
        try {
            /**
             * 这个 ffmpeg 命令用于提取输入视频文件的第一帧，并将其按指定比例进行缩放。下面是对该命令中各个参数的解释：
             * - `-i %s`：表示输入文件的路径和文件名，`%s` 是一个占位符，需要被实际的文件路径和文件名替换。
             * - `-y`：表示在输出文件存在时，直接覆盖输出文件，而不进行询问确认。
             * - `-vframes 1`：表示只提取输入视频文件的第一帧。
             * - `-vf scale=%d:%d/a`：表示使用视频滤镜（`-vf`）进行缩放操作，`scale=%d:%d/a` 是一个占位符，需要被实际的宽度和高度替换。
             * 其中 `%d` 是宽度和高度的占位符，`/a` 表示按照原始宽高比进行缩放。
             * 综合起来，该命令的作用是从输入的视频文件中提取第一帧，并按照指定的宽度和高度进行缩放。
             * 输出的文件将覆盖同名的已存在文件（如果有），而不进行确认提示。
             * 请注意，`%s`、`%d` 是占位符，实际使用时需要将其替换为实际的文件路径、宽度和高度值。
             * 此外，该命令还可以根据需要添加其他参数来进行更多的视频处理操作，例如调整帧率、添加水印等。
             */
            String cmd = "ffmpeg -i %s -y -vframes 1 -vf scale=%d:%d/a %s";
            ProcessUtils.executeCommand(String.format(cmd, sourceFile.getAbsoluteFile(), width, width, targetFile.getAbsoluteFile()), false);
        } catch (Exception e) {
            logger.error("生成视频封面失败", e);
        }
    }

    /**
     *  生成图片的缩略图
     * @param file 文件
     * @param thumbnailWidth
     * @param targetFile
     * @param delSource
     * @return
     */
    public static Boolean createThumbnailWidthFFmpeg(File file, int thumbnailWidth, File targetFile, Boolean delSource) {
        try {
            BufferedImage src = ImageIO.read(file);
            //thumbnailWidth 缩略图的宽度   thumbnailHeight 缩略图的高度
            int sorceW = src.getWidth();
            int sorceH = src.getHeight();
            //小于 指定高宽不压缩
            if (sorceW <= thumbnailWidth) {
                return false;
            }
            compressImage(file, thumbnailWidth, targetFile, delSource);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void compressImageWidthPercentage(File sourceFile, BigDecimal widthPercentage, File targetFile) {
        try {
            BigDecimal widthResult = widthPercentage.multiply(new BigDecimal(ImageIO.read(sourceFile).getWidth()));
            compressImage(sourceFile, widthResult.intValue(), targetFile, true);
        } catch (Exception e) {
            logger.error("压缩图片失败");
        }
    }
    public static void compressImage(File sourceFile, Integer width, File targetFile, Boolean delSource) {
        try {
            String cmd = "ffmpeg -i %s -vf scale=%d:-1 %s -y";
            ProcessUtils.executeCommand(String.format(cmd, sourceFile.getAbsoluteFile(), width, targetFile.getAbsoluteFile()), false);
            if (delSource) {
                FileUtils.forceDelete(sourceFile);
            }
        } catch (Exception e) {
            logger.error("压缩图片失败");
        }
    }

    public static void main(String[] args) {
        compressImageWidthPercentage(new File("C:\\Users\\Administrator\\Pictures\\微信图片_20230107141436.png"), new BigDecimal(0.7),
                new File("C:\\Users\\Administrator" +
                        "\\Pictures" +
                        "\\微信图片_202106281029182.jpg"));
    }
}